package com.lp.biz.train.service.impl;
import java.time.LocalDateTime;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.lp.biz.content.mapper.BizCoreContentMapper;
import com.lp.biz.content.model.entity.BizCoreContent;
import com.lp.biz.identity.model.entity.BizIdentity;
import com.lp.biz.message.model.entity.BizMessageSystem;
import com.lp.biz.message.service.BizMessageSystemService;
import com.lp.biz.train.mapper.*;
import com.lp.biz.train.model.entity.*;
import com.lp.biz.train.model.query.*;
import com.lp.biz.train.model.vo.*;
import com.lp.biz.train.service.BizTrainClassService;
import com.lp.common.context.ContextHolder;
import com.lp.common.context.UserDetail;
import com.lp.common.entity.PageParams;
import com.lp.common.exception.BaseException;
import com.lp.common.exception.ErrorCodeEnum;
import com.lp.common.utils.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

import static com.lp.common.constant.CommentConstant.TYPE_COMMENT;
import static com.lp.common.constant.CommentConstant.TYPE_REPLY;
import static com.lp.common.constant.CommonConstant.NEGATE;
import static com.lp.common.constant.CommonConstant.SURE;
import static com.lp.common.constant.IdentityConstant.*;
import static com.lp.common.constant.RoleConstant.ADMIN;
import static com.lp.common.constant.TrainConstant.*;
import static com.lp.common.utils.Tools.sortHandler;

/**
 * @program: backend
 * @description:
 * @author: Ke.Song
 * @since: 2024-05-23 21:33:54
 */
@Slf4j
@Service
public class BizTrainClassServiceImpl extends ServiceImpl<BizTrainClassMapper, BizTrainClass> implements BizTrainClassService {

    @Autowired
    private BizTrainTaskMapper taskMapper;

    @Autowired
    private BizTrainClassMapper classMapper;

    @Autowired
    private BizTrainChapterMapper chapterMapper;

    @Autowired
    private BizTrainClassVoteMapper voteMapper;

    @Autowired
    private BizTrainTaskTypeMapper taskTypeMapper;

    @Autowired
    private BizCoreContentMapper coreContentMapper;

    @Autowired
    private BizMessageSystemService messageSystemService;

    @Autowired
    private BizTrainClassChapterRelMapper chapterRelMapper;

    @Autowired
    private BizTrainTaskMemberRelMapper taskMemberRelMapper;

    @Autowired
    private BizTrainHomeworkClassMapper homeworkClassMapper;

    @Autowired
    private BizTrainTaskModeratorMapper taskModeratorMapper;

    @Autowired
    private BizTrainClassMemberRelMapper classMemberRelMapper;

    @Autowired
    private BizTrainHomeworkResourceImgMapper resourceImgMapper;

    @Autowired
    private BizTrainHomeworkCommentMapper homeworkCommentMapper;

    @Autowired
    private BizTrainHomeworkResourceVideoMapper resourceVideoMapper;

    @Autowired
    private BizTrainHomeworkResourceAudioMapper resourceAudioMapper;

    @Autowired
    private BizTrainClassMemberManageMapper classMemberManageMapper;

    @Override
    public CommonResult getClasses(PageParams query) {
        UserDetail userDetail = ContextHolder.getContext().getUserDetail();
        PageHelper.startPage(query.getPage(), query.getSize());
        List<ClassList> classes;
        if (userDetail.getRoles().contains(ADMIN)) {
            classes = classMapper.getClasses(null);
        } else {
            classes = classMapper.getClasses(userDetail.getId());
        }
        LocalDate now = LocalDate.now();
        for (ClassList aClass : classes) {
            if (aClass.getStartAt() != null && aClass.getEndAt() != null) {
                if (aClass.getStartAt().isAfter(now)) {
                    aClass.setStatus(CLASS_NOT_START);
                } else if (aClass.getEndAt().isBefore(now)) {
                    aClass.setStatus(CLASS_ENDED);
                } else {
                    aClass.setStatus(CLASS_STARTED);
                }
            }
        }
        return CommonResult.restPage(classes);
    }

    @Override
    public CommonResult getClassDetail(Integer classId) {
        checkClass(classId);
        ClassDetail classDetail = classMapper.getClassDetail(classId);
        if (classDetail.getStartAt() != null) {
            classDetail.setClassTeacher(classMapper.getClassTeacher(classId));
            classDetail.setTrainer(classMapper.getClassTrainer(classId));
            classDetail.setAssistant(classMapper.getClassAssistant(classId));
            classDetail.setMentor(classMapper.getClassMentor(classId));
            LocalDate now = LocalDate.now();
            if (classDetail.getStartAt().isAfter(now)) {
                classDetail.setStatus(CLASS_NOT_START);
            } else if (classDetail.getEndAt().isBefore(now)) {
                classDetail.setStatus(CLASS_ENDED);
            } else {
                classDetail.setStatus(CLASS_STARTED);
            }
        }
        return CommonResult.success(classDetail);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void updateClassDate(Integer classId, ClassUpdateDate params) {
        // 根据班级ID查询班级信息
        BizTrainClass bizTrainClass = checkClass(classId);
        LocalDate now = LocalDate.now();

        if (bizTrainClass.getStartAt() != null && !now.isBefore(bizTrainClass.getStartAt())) {
            // 班级已开营时抛出异常
            log.info("班级时间：班级已开营，班级：{}, 开营时间：{}", bizTrainClass.getName(), bizTrainClass.getStartAt());
            throw new BaseException("所选班级已开营");
        } else if (!params.getStartAt().isBefore(params.getEndAt())) {
            // 输入的日期参数不正确时抛出异常
            log.info("班级时间：输入参数错误，开始时间：{}， 结束时间：{}", params.getStartAt(), params.getEndAt());
            throw new BaseException("结束时间早于开始时间");
        } else if (params.getStartAt().isBefore(now)) {
            // 输入的日期参数不正确时抛出异常
            log.info("班级时间：参数错误，开始时间：{}， 结束时间：{}", params.getStartAt(), params.getEndAt());
            throw new BaseException("开始时间早于当前时间");
        }

        // 更新班级的开课和结束日期
        bizTrainClass.setStartAt(params.getStartAt());
        bizTrainClass.setEndAt(params.getEndAt());
        classMapper.updateById(bizTrainClass);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void deleteClass(Integer classId) {
        BizTrainClass trainClass = classMapper.selectById(classId);
        if (trainClass == null) {
            throw new BaseException("班级输入错误");
        }
        if (trainClass.getStartAt() != null && !trainClass.getStartAt().isBefore(LocalDate.now())) {
            Long l = classMemberRelMapper.selectCount(new QueryWrapper<BizTrainClassMemberRel>().lambda()
                    .eq(BizTrainClassMemberRel::getBizTrainClassId, classId)
                    .eq(BizTrainClassMemberRel::getBizIdentityCode, STUDENT)
                    .eq(BizTrainClassMemberRel::getIsDeleted, NEGATE));
            if (l != null && l > 0) {
                throw new BaseException("班级不能删除");
            }
        }
        classMapper.deleteClass(classId);
    }

    @Override
    public CommonResult getClassChapter(Integer classId, ClassChapterQuery query) {
        checkClass(classId);
        PageHelper.startPage(query.getPage(), query.getSize());
        return CommonResult.restPage(chapterRelMapper.getClassChapter(classId,
                StringUtils.isBlank(query.getTitle()) ? null : query.getTitle()));
    }

    @Override
    public CommonResult getClassMemberList(Integer classId, ClassMemberQuery query) {
        checkClass(classId);
        PageHelper.startPage(query.getPage(), query.getSize());
        query.setNickName(StringUtils.isBlank(query.getNickName()) ? null : query.getNickName());
        query.setPhone(StringUtils.isBlank(query.getPhone()) ? null : query.getPhone());
        return CommonResult.restPage(classMemberRelMapper.getClassMemberList(classId, query.getNickName(), query.getPhone()));
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void publishChapter(Integer classId, Integer chapterId) {
        // 根据班级ID查询班级信息
        BizTrainClass trainClass = checkClass(classId);
        if (trainClass.getStartAt() == null || trainClass.getEndAt() == null) {
            throw new BaseException("班级未开营");
        }
        BizTrainChapter bizTrainChapter = chapterMapper.selectById(chapterId);
        if (bizTrainChapter == null || ObjectUtil.notEqual(bizTrainChapter.getBizTrainId(), trainClass.getBizTrainId()) || bizTrainChapter.getIsDeleted().equals(SURE)) {
            throw new BaseException("章节错误");
        } else if (bizTrainChapter.getIsDisplay().equals(NEGATE)) {
            throw new BaseException("章节未上架");
        }
        chapterRelMapper.update(null, new UpdateWrapper<BizTrainClassChapterRel>().lambda()
                .eq(BizTrainClassChapterRel::getBizTrainClassId, classId)
                .eq(BizTrainClassChapterRel::getBizTrainChapterId, chapterId)
                .eq(BizTrainClassChapterRel::getIsDeleted, NEGATE)
                .eq(BizTrainClassChapterRel::getIsPublished, NEGATE)
                .set(BizTrainClassChapterRel::getIsPublished, SURE));
    }

    @Override
    public CommonResult getClassManage(Integer classId) {
        checkClass(classId);
        return CommonResult.success(classMapper.getClassManage(classId));
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void assignToManager(Integer classId, ClassAssignMember assignMember) {
        // 检查班级是否存在
        checkClass(classId);
        ClassManage manage = null;
        // 查找指定ID的管理员
        for (ClassManage classManage : classMapper.getClassManage(classId)) {
            if (classManage.getId().equals(assignMember.getManagerId())) {
                manage = classManage;
                break;
            }
        }
        // 如果没有找到对应的管理员，抛出异常
        if (manage == null) {
            throw new BaseException(ErrorCodeEnum.PARAMS_ERROR);
        }
        // 校验要分配的学生数量是否和传入的列表一致
        Long l = classMemberRelMapper.selectCount(new QueryWrapper<BizTrainClassMemberRel>().lambda()
                .eq(BizTrainClassMemberRel::getBizTrainClassId, classId)
                .eq(BizTrainClassMemberRel::getBizIdentityCode, STUDENT)
                .in(BizTrainClassMemberRel::getMemberId, assignMember.getMemberList()));
        if (l == null || l.intValue() != assignMember.getMemberList().size()) {
            throw new BaseException(ErrorCodeEnum.PARAMS_ERROR);
        }
        // 先删除原有的管理员和成员关系
        classMemberManageMapper.delete(new QueryWrapper<BizTrainClassMemberManage>().lambda()
                .eq(BizTrainClassMemberManage::getBizTrainClassId, classId)
                .in(BizTrainClassMemberManage::getMemberId, assignMember.getMemberList()));
        // 构建新的管理员和成员关系列表
        List<BizTrainClassMemberManage> relList = new ArrayList<>(6);
        for (Integer memberId : assignMember.getMemberList()) {
            BizTrainClassMemberManage classMemberManage = new BizTrainClassMemberManage();
            // 设置关系信息
            classMemberManage.setMemberId(memberId);
            classMemberManage.setManageId(assignMember.getManagerId());
            classMemberManage.setMenageIdentityId(manage.getIdentityId());
            classMemberManage.setMenageIdentityCode(manage.getIdentityCode());
            classMemberManage.setBizTrainClassId(classId);
            classMemberManage.setCreateAt(LocalDateTime.now());
            relList.add(classMemberManage);
        }
        // 如果有新的关系需要建立，则批量插入这些关系
        if (!relList.isEmpty()) {
            classMemberManageMapper.insertBatch(relList);
        }
    }

    @Override
    public CommonResult getClassHomeworks(Integer classId, PageParams query) {
        checkClass(classId);
        PageHelper.startPage(query.getPage(), query.getSize());
        return CommonResult.restPage(homeworkClassMapper.getClassHomeworks(classId));
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void publishClassHomework(Integer classId, Integer homeworkId) {
        checkClass(classId);
        BizTrainHomeworkClass homeworkClass = homeworkClassMapper.selectById(homeworkId);
        if (homeworkClass == null || homeworkClass.getIsDeleted().equals(SURE)
                || homeworkClass.getIsEnabled().equals(SURE)
                || !homeworkClass.getBizTrainClassId().equals(classId)) {
            throw new BaseException(ErrorCodeEnum.PARAMS_ERROR);
        }
        homeworkClass.setIsEnabled(SURE);
        homeworkClass.setPublishedAt(LocalDateTime.now());
        homeworkClassMapper.updateById(homeworkClass);
    }

    @Override
    public CommonResult submittedComment(Integer classId, SubmittedHomeworkQuery query) {
        checkClass(classId);
        PageHelper.startPage(query.getPage(), query.getSize());
        query.setNickName(StringUtils.isBlank(query.getNickName()) ? null : query.getNickName());
        query.setPhone(StringUtils.isBlank(query.getPhone()) ? null : query.getPhone());
        return CommonResult.restPage(homeworkClassMapper.submittedComment(classId, query.getNickName(), query.getPhone()));
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void commentTop(Integer classId, Integer commentId) {
        // 获取当前操作成员的ID
        Integer memberId = ContextHolder.getContext().getMemberId();
        // 查询指定评论信息
        BizTrainHomeworkComment comment = checkComment(classId, commentId);
        // 如果评论已经是顶状态，则取消顶状态；否则设置为顶状态
        if (SURE == comment.getIsTop()) {
            homeworkCommentMapper.update(null, new UpdateWrapper<BizTrainHomeworkComment>().lambda()
                    .eq(BizTrainHomeworkComment::getId, commentId)
                    .set(BizTrainHomeworkComment::getIsTop, NEGATE)
                    .set(BizTrainHomeworkComment::getTopAt, null)
                    .set(BizTrainHomeworkComment::getTopMemberId, null));
        } else {
            homeworkCommentMapper.update(null, new UpdateWrapper<BizTrainHomeworkComment>().lambda()
                    .eq(BizTrainHomeworkComment::getId, commentId)
                    .set(BizTrainHomeworkComment::getIsTop, SURE)
                    .set(BizTrainHomeworkComment::getTopAt, LocalDateTime.now())
                    .set(BizTrainHomeworkComment::getTopMemberId, memberId));
        }
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void deleteComment(Integer classId, Integer commentId) {
        BizTrainHomeworkComment comment = checkComment(classId, commentId);
        comment.setIsDeleted(SURE);
        homeworkCommentMapper.updateById(comment);
    }

    @Override
    public CommonResult unsubmittedComment(Integer classId, SubmittedHomeworkQuery query) {
        checkClass(classId);
        PageHelper.startPage(query.getPage(), query.getSize());
        query.setNickName(StringUtils.isBlank(query.getNickName()) ? null : query.getNickName());
        query.setPhone(StringUtils.isBlank(query.getPhone()) ? null : query.getPhone());
        return CommonResult.restPage(homeworkClassMapper.unsubmittedComment(classId, query.getNickName(), query.getPhone()));
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void addComment(Integer classId, Integer commentId, ClassAddComment addComment) {
        Integer memberId = ContextHolder.getContext().getMemberId();
        BizTrainHomeworkComment comment = checkComment(classId, commentId);
        BizTrainHomeworkComment newComment = new BizTrainHomeworkComment();
        newComment.setBizTrainId(comment.getBizTrainId());
        newComment.setBizTrainClassId(comment.getBizTrainClassId());
        newComment.setBizTrainHomeworkId(comment.getBizTrainHomeworkId());
        newComment.setMemberId(memberId);
        newComment.setContent(addComment.getComment());
        newComment.setCommenteeId(comment.getMemberId());
        newComment.setParentId(commentId);
        newComment.setBizTrainCommentId(commentId);
        newComment.setType(TYPE_REPLY);
        newComment.setIsComment(SURE);
        newComment.setCreateAt(LocalDateTime.now());
        homeworkCommentMapper.insert(newComment);
    }

    @Override
    public CommonResult getComment(Integer classId, Integer commentId) {
        BizTrainHomeworkComment comment = getCommentByCheck(classId, commentId);
        ClassCommentDetail detail = new ClassCommentDetail();
        detail.setContent(comment.getContent());
        detail.setImageUrlList(new ArrayList<>());
        for (BizTrainHomeworkResourceImg img : resourceImgMapper.selectList(
                new QueryWrapper<BizTrainHomeworkResourceImg>().lambda()
                        .eq(BizTrainHomeworkResourceImg::getBizTrainCommentId, commentId)
                        .eq(BizTrainHomeworkResourceImg::getIsDelete, NEGATE)
                        .orderByAsc(BizTrainHomeworkResourceImg::getSort))) {
            detail.getImageUrlList().add(img.getPath());
        }
        BizTrainHomeworkResourceVideo video = resourceVideoMapper.selectOne(
                new QueryWrapper<BizTrainHomeworkResourceVideo>().lambda()
                        .eq(BizTrainHomeworkResourceVideo::getBizTrainCommentId, commentId)
                        .eq(BizTrainHomeworkResourceVideo::getIsDelete, NEGATE));
        if (video != null) {
            detail.setVideoUrl(video.getPath());
        }
        BizTrainHomeworkResourceAudio audio = resourceAudioMapper.selectOne(
                new QueryWrapper<BizTrainHomeworkResourceAudio>().lambda()
                        .eq(BizTrainHomeworkResourceAudio::getBizTrainCommentId, commentId)
                        .eq(BizTrainHomeworkResourceAudio::getIsDelete, NEGATE));
        if (audio != null) {
            detail.setAudioUrl(audio.getPath());
        }
        for (BizTrainHomeworkComment temp : homeworkCommentMapper.selectList(new QueryWrapper<BizTrainHomeworkComment>().lambda()
                .eq(BizTrainHomeworkComment::getBizTrainClassId, comment.getBizTrainClassId())
                .eq(BizTrainHomeworkComment::getParentId, comment.getId())
                .eq(BizTrainHomeworkComment::getType, TYPE_REPLY)
                .eq(BizTrainHomeworkComment::getIsDeleted, NEGATE)
                .eq(BizTrainHomeworkComment::getIsComment, SURE)
                .orderByDesc(BizTrainHomeworkComment::getCreateAt))) {
            detail.setComment(temp.getContent());
            break;
        }
        return CommonResult.success(detail);
    }

    @Override
    public CommonResult getEvents(Integer classId, PageParams query) {
        checkClass(classId);
        PageHelper.startPage(query.getPage(), query.getSize());
        List<ClassEvents> events = taskMapper.getEvents(classId);
        LocalDateTime now = LocalDateTime.now();
        for (ClassEvents event : events) {
            if (now.isBefore(event.getStartAt())) {
                event.setStatus(CLASS_NOT_START);
            } else if (now.isAfter(event.getEndAt())) {
                event.setStatus(CLASS_ENDED);
            } else {
                event.setStatus(CLASS_STARTED);
            }
        }
        return CommonResult.restPage(events);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void addEvents(ClassEventsCreate event, Integer classId) {
        Integer memberId = ContextHolder.getContext().getMemberId();
        BizTrainClass trainClass = checkClass(classId);
        BizTrainTask task = new BizTrainTask();
        task.setBizTrainClassId(classId);
        task.setTheme(event.getTheme());
        task.setLocal(event.getLocal());
        task.setContent(event.getContent());
        task.setMemberId(memberId);
        task.setStartAt(event.getStartAt());
        task.setEndAt(event.getEndAt());
        task.setCreateAt(LocalDateTime.now());
        BizTrainTaskType taskType = taskTypeMapper.selectById(event.getTypeId());
        if (taskType == null) {
            throw new BaseException("活动类型输入错误");
        }
        task.setTypeId(event.getTypeId());
        task.setTypeCode(taskType.getCode());
        taskMapper.insert(task);
        taskMemberRelMapper.initTaskMemberRel(task.getId(), classId);
        List<BizMessageSystem> messages = new ArrayList<>();
        for (BizTrainClassMemberRel rel : classMemberRelMapper.selectList(new QueryWrapper<BizTrainClassMemberRel>()
                .lambda().eq(BizTrainClassMemberRel::getBizTrainClassId, classId)
                .eq(BizTrainClassMemberRel::getBizIdentityCode, STUDENT))) {
            messages.add(messageSystemService.inActivity(rel.getMemberId(), trainClass));
        }
        messageSystemService.insertBatch(messages);
    }

    @Override
    public CommonResult getEventSignUp(Integer classId, Integer eventId, PageParams query) {
        checkTask(classId, eventId);
        BizTrainTaskModerator moderator = taskModeratorMapper.selectOne(new QueryWrapper<BizTrainTaskModerator>()
                .lambda().eq(BizTrainTaskModerator::getBizTrainTaskId, eventId));
        PageHelper.startPage(query.getPage(), query.getSize());
        List<TaskSignUps> dataList = taskMapper.getEventSignUp(classId, eventId);
        for (TaskSignUps data : dataList) {
            if (moderator != null) {
                data.setIsHasModerator(SURE);
            } else {
                data.setIsHasModerator(NEGATE);
            }
        }
        return CommonResult.restPage(dataList);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void updateModerator(Integer classId, Integer eventId, ClassModerator moderator) {
        checkTask(classId, eventId);

        // 尝试根据任务ID查询已存在的管理员信息
        BizTrainTaskModerator taskModerator = taskModeratorMapper.selectOne(new QueryWrapper<BizTrainTaskModerator>()
                .lambda().eq(BizTrainTaskModerator::getBizTrainTaskId, eventId));

        if (taskModerator == null) {
            // 不存在管理员信息时，创建并插入新的管理员信息
            taskModerator = new BizTrainTaskModerator();
            taskModerator.setBizTrainTaskId(eventId);
            taskModerator.setMemberId(moderator.getMemberId());
            taskModeratorMapper.insert(taskModerator);
        } else if (!taskModerator.getMemberId().equals(moderator.getMemberId())) {
            // 管理员ID不一致时，抛出参数错误异常
            throw new BaseException(ErrorCodeEnum.PARAMS_ERROR);
        } else {
            // 存在且管理员ID一致时，删除原有管理员信息
            taskModeratorMapper.delete(new QueryWrapper<BizTrainTaskModerator>()
                    .lambda().eq(BizTrainTaskModerator::getBizTrainTaskId, eventId));
        }
    }

    @Override
    public CommonResult getNotEnrolled(Integer classId, Integer eventId, PageParams query) {
        checkTask(classId, eventId);
        PageHelper.startPage(query.getPage(), query.getSize());
        return CommonResult.restPage(taskMapper.getNotEnrolled(classId, eventId));
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void startVote(Integer classId, ClassVoteCreate classVote) {
        BizTrainClass trainClass = checkClass(classId);
        LocalDate now = LocalDate.now();
        if (classVote.getStartAt().toLocalDate().isBefore(now) || !classVote.getStartAt().isBefore(classVote.getEndAt())) {
            throw new BaseException("时间输入错误");
        }
        if (VOTE_START == trainClass.getIsVote()) {
            throw new BaseException("投票已开始");
        }
        if (VOTE_END == trainClass.getIsVote()) {
            throw new BaseException("投票已结束");
        }
        if (classVote.getTopNum() <= 0) {
            throw new BaseException("奖励数量过少");
        }
        int num = 0;
        int published = 0;
        for (BizTrainClassChapterRel rel : chapterRelMapper.selectList(new QueryWrapper<BizTrainClassChapterRel>()
                .lambda().eq(BizTrainClassChapterRel::getBizTrainClassId, classId)
                .eq(BizTrainClassChapterRel::getIsDeleted, NEGATE))) {
            num ++;
            if (rel.getIsPublished().equals(SURE)) {
                published ++;
            }
        }
        if (published < num) {
            throw new BaseException("章节未全部发布");
        }
        trainClass.setIsVote(VOTE_START);
        trainClass.setStartVotingAt(classVote.getStartAt());
        trainClass.setEndVotingAt(classVote.getEndAt());
        trainClass.setRewardNum(classVote.getTopNum());
        classMapper.updateById(trainClass);
    }

    @Override
    public CommonResult getVoteDetail(Integer classId) {
        BizTrainClass bizTrainClass = checkClass(classId);
        ClassVoteDetail detail = new ClassVoteDetail();
        detail.setStatus(bizTrainClass.getIsVote());
        detail.setTopNum(bizTrainClass.getRewardNum());
        detail.setStartAt(bizTrainClass.getStartVotingAt());
        detail.setEndAt(bizTrainClass.getEndVotingAt());
        return CommonResult.success(detail);
    }

    @Override
    public CommonResult getVoteMembers(Integer classId, ClassVoteMembersQuery query) {
        checkClass(classId);
        if (query.getStatus() != null) {
            if (!(query.getStatus().equals(NEGATE) || query.getStatus().equals(SURE))) {
                throw new BaseException(ErrorCodeEnum.PARAMS_ERROR);
            }
        }
        PageHelper.startPage(query.getPage(), query.getSize());
        return CommonResult.restPage(voteMapper.getVoteMembers(classId, query.getNickName(), query.getStatus(),
                sortHandler(query.getSort())));
    }

    private BizTrainClass checkClass(Integer classId) {
        UserDetail userDetail = ContextHolder.getContext().getUserDetail();
        BizTrainClass bizTrainClass = classMapper.selectById(classId);
        if (bizTrainClass == null || bizTrainClass.getIsDeleted().equals(SURE)) {
            log.info("班级校验：班级不存在，请求参数：{}", classId);
            throw new BaseException(ErrorCodeEnum.PARAMS_ERROR);
        } else {
            BizCoreContent content = coreContentMapper.selectById(bizTrainClass.getBizTrainId());
            if (content == null || content.getIsDeleted().equals(SURE) || content.getIsDisplay().equals(NEGATE)) {
                throw new BaseException(ErrorCodeEnum.PARAMS_ERROR);
            }
        }
        if (!userDetail.getRoles().contains(ADMIN)) {
            Long count = classMemberRelMapper.selectCount(new QueryWrapper<BizTrainClassMemberRel>().lambda()
                    .eq(BizTrainClassMemberRel::getBizTrainClassId, classId)
                    .eq(BizTrainClassMemberRel::getMemberId, userDetail.getId())
                    .eq(BizTrainClassMemberRel::getBizIdentityCode, CLASS_TEACHER));
            if (count == 0) {
                log.info("班级校验：用户不是班级班主任, 班级：{}， 用户：{}", bizTrainClass.getName(), userDetail.getNickName());
                throw new BaseException(ErrorCodeEnum.PARAMS_ERROR);
            }
        }
        return bizTrainClass;
    }

    @Override
    public CommonResult getGraduationList(ClassGraduationQuery query) {
        PageHelper.startPage(query.getPage(), query.getSize());
        return CommonResult.restPage(classMemberRelMapper.getGraduationList(query));
    }

    @Override
    public CommonResult getTaskType() {
        return CommonResult.success(taskTypeMapper.selectList(new QueryWrapper<>()));
    }

    private BizTrainHomeworkComment checkComment(Integer classId, Integer commentId) {
        BizTrainHomeworkComment comment = getCommentByCheck(classId, commentId);
        // 根据成员ID查询其在课堂中的身份
        BizIdentity identity = classMemberRelMapper.getIdentityByMember(classId, comment.getMemberId());
        // 如果评论作者是教练，则抛出权限异常
        if (identity.getCategory().equals(CATEGORY_TRAINER)) {
            throw new BaseException(ErrorCodeEnum.PERMISSION_ERROR);
        }
        return comment;
    }

    private BizTrainHomeworkComment getCommentByCheck(Integer classId, Integer commentId) {
        checkClass(classId);
        BizTrainHomeworkComment comment = homeworkCommentMapper.selectOne(new QueryWrapper<BizTrainHomeworkComment>().lambda()
                .eq(BizTrainHomeworkComment::getId, commentId)
                .eq(BizTrainHomeworkComment::getBizTrainClassId, classId)
                .eq(BizTrainHomeworkComment::getType, TYPE_COMMENT)
                .eq(BizTrainHomeworkComment::getIsDeleted, NEGATE));
        if (comment == null) {
            throw new BaseException(ErrorCodeEnum.PARAMS_ERROR);
        }
        return comment;
    }

    private void checkTask(Integer classId, Integer eventId) {
        checkClass(classId);
        BizTrainTask task = taskMapper.selectById(eventId);
        if (task == null || !task.getBizTrainClassId().equals(classId)) {
            throw new BaseException(ErrorCodeEnum.PARAMS_ERROR);
        }
    }
}
